package cn.westv.scps.web.controller.base;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import cn.westv.scps.domain.SysConfig;
import cn.westv.scps.exception.BussinessException;
import cn.westv.scps.service.sys.config.ISysConfigService;
import cn.westv.scps.utils.SpringContextUtil;
import cn.westv.scps.utils.StringUtils;

/**
 */
public abstract class AbstractController<T> {

	private static final int PAGE = 1;
	private static final int PAGE_SIZE = 10;
	public static final String SESSION_USER_INFO = "user";

	protected Logger logger = Logger
			.getLogger((Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]);

	// private String ipAddr;

	// protected HttpServletRequest request;

	// protected HttpServletResponse response;
	// protected HttpSession session;

	protected HttpServletRequest getRequest() {
		return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
	}

	// protected HttpServletResponse getResponse()
	// {
	// ServletWebRequest webRequest = new ServletWebRequest(getRequest());
	// return webRequest.getResponse();
	// }

	protected HttpSession getSession() {
		return getRequest().getSession();
	}

	protected PropertiesFactoryBean propertiesFactory;

	/**
	 * 
	 * 
	 * 判断对某个action 方法时候具有权限，在action方法调用之前，验证方法权限，根据结果进行相应处理
	 * ，action二进制值和注意是资源id不是资源typeId<br/>
	 * <br/>
	 * <p>
	 * Author: leiyu<br/>
	 * <p>
	 * Date: 2014-4-2-下午2:12:40<br/>
	 * <p>
	 * 
	 * @param
	 * @param
	 * @return
	 * 
	 */
	protected boolean hasPermission(String actionCode) {
		return true;
	}

	/**
	 * 封装ajax返回Map的信息<br/>
	 * <p>
	 * Description: 将ajax方法返回的Map信息进行统一的封装，使用时只需调用此方法传入参数即可。<br>
	 * <p>
	 * 如果自定义消息customMsgDesc不为空则使用customMsgDesc，否则根据msgDesc去查找相应的异常信息。 <br/>
	 * <p>
	 * Author: dencl<br/>
	 * <p>
	 * Date: 2014-4-2-下午2:49:13<br/>
	 * <p>
	 * 
	 * @param opResult
	 *            结果
	 * @param msgType
	 *            消息类型
	 * @param msgDesc
	 *            消息描述
	 * @param customMsgDesc
	 *            自定义消息
	 * @return
	 * 
	 */
	protected Map<String, String> packageAjaxReturnMap(String opResult, String msgType, String msgDesc,
			String customMsgDesc) {
		Map<String, String> map = new HashMap<String, String>(4);

		map.put(ERROR_KEY_OP_RESULT, opResult);
		map.put(ERROR_KEY_MSG_TYPE, msgType);

		if (StringUtils.isNotBlank(customMsgDesc)) {
			map.put(ERROR_KEY_MSG_DESC, customMsgDesc);
		} else {
			map.put(ERROR_KEY_MSG_DESC, "");
		}

		return map;

	}

	protected Map<String, String> ajaxReturnMap(String opStatus, String msgDesc) {
		Map<String, String> map = new HashMap<String, String>(2);
		map.put(KEY_OP_STATUS, opStatus);
		map.put(KEY_MSG_DESC, msgDesc);
		return map;

	}

	protected Map<String, Object> ajaxReturnMap(String opStatus, String msgDesc, Object data) {
		Map<String, Object> map = new HashMap<String, Object>(2);
		map.put(KEY_OP_STATUS, opStatus);
		map.put(KEY_MSG_DESC, msgDesc);
		map.put(KEY_DATA, data);
		return map;
	}

	// protected Map<String, Object> ajaxPageMap(PaginationList<?> plist,
	// List<?> pageData)
	// {
	// final String PAGE_NUMBER = "pageNumber";
	// final String PAGE_SIZE = "pageSize";
	// final String TOTAL_PAGE = "totalPage";
	// final String TOTAL_RECORD = "totalRecord";
	// final String PAGE_DATA = "pageData";
	// Map<String, Object> map = new HashMap<String, Object>();
	// map.put(PAGE_NUMBER, plist.getPageNumber());
	// map.put(PAGE_SIZE, plist.getObjectsPerPage());
	// map.put(TOTAL_PAGE, plist.getPageCount());
	// map.put(TOTAL_RECORD, plist.getFullListSize());
	// map.put(PAGE_DATA, pageData);
	// return map;
	//
	// }

	/**
	 * 获取错误信息 <br/>
	 * <p>
	 * Description: 通过异常名获取返回的错误信息 <br/>
	 * <p>
	 * Author: leiyu<br/>
	 * <p>
	 * Date: 2014-4-2-下午2:49:13<br/>
	 * <p>
	 * 
	 * @param exceptionName
	 * @return 异常对应的错误信息
	 * 
	 */
	protected String getErrorMessage(String exceptionName) {
		try {
			return ((Properties) (propertiesFactory.getObject())).getProperty(exceptionName);
		} catch (IOException e) {
			// handleException(e);
			return "错误信息配置文件加载错误";
		}
	}

	protected int getPage() {
		String pageString = getRequest().getParameter("page");

		if (StringUtils.isNotBlank(pageString)) {
			return Integer.parseInt(pageString);
		}

		return PAGE;
	}

	protected int getPageSize() {
		String pageSizeString = getRequest().getParameter("rows");
		if (StringUtils.isBlank(pageSizeString)) {
			pageSizeString = getRequest().getParameter("pageSize");
		}
		if (StringUtils.isNotBlank(pageSizeString)) {
			return Integer.parseInt(pageSizeString);
		}

		return PAGE_SIZE;
	}

	// @ModelAttribute
	// public void setReqAndResp(HttpServletRequest request, HttpServletResponse
	// response)
	// {
	// this.request = request;
	// this.response = response;
	// this.session = this.request.getSession();
	// this.setIpAddr(request);
	// }

	protected String getIpAddr() {
		return StringUtils.getIpAddr(getRequest());
	}

	/**
	 * 允许跨域访问
	 * 
	 * @param response
	 */
	protected void setResponseToOpen(HttpServletResponse response) {
		response.setHeader("Access-Control-Allow-Origin", "*");
		response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
		response.setHeader("Access-Control-Max-Age", "3600");
		response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
	}

	@ExceptionHandler
	// @ResponseBody
	public String exceptionHandler(HttpServletRequest request, Exception e) {
		request.setAttribute("ex", e);
		logger.error(e.getMessage());
		if (e instanceof BussinessException) {

		}
		return "";

	}

	/**
	 * @Fields OP_STATUS_SUCCESS :
	 */
	public static final String OP_STATUS_SUCCESS = "0";

	/**
	 * @Fields OP_STATUS_FAILD :
	 */
	public static final String OP_STATUS_FAILD = "1";

	/**
	 * @Fields OP_STATUS_FAILD :
	 */
	public static final String KEY_OP_STATUS = "opStatus";
	/**
	 * @Fields OP_STATUS_FAILD :
	 */
	public static final String KEY_MSG_DESC = "msgDesc";
	/**
	 * @Fields OP_STATUS_FAILD :
	 */
	public static final String KEY_DATA = "data";

	/**
	 * @Fields ERROR_KEY_MSG_TYPE : 返回值的key msgType
	 */
	public static final String ERROR_KEY_MSG_TYPE = "msgType";

	/**
	 * @Fields ERROR_KEY_MSG_DESC : 返回值的key msgDesc
	 */
	public static final String ERROR_KEY_MSG_DESC = "msgDesc";

	/**
	 * @Fields ERROR_KEY_OP_RESULT : 返回值的key opResult
	 */
	public static final String ERROR_KEY_OP_RESULT = "opResult";

	/**
	 * @Fields ERROR_VALUE_MSG_TYPE_INFO : 返回值的value 消息
	 */
	public static final String ERROR_VALUE_MSG_TYPE_INFO = "info";

	/**
	 * @Fields ERROR_VALUE_MSG_TYPE_WARN : 返回值的value 警告
	 */
	public static final String ERROR_VALUE_MSG_TYPE_WARN = "warning";

	/**
	 * @Fields ERROR_VALUE_MSG_TYPE_QUESTION : 返回值的value 疑问
	 */
	public static final String ERROR_VALUE_MSG_TYPE_QUESTION = "question";

	/**
	 * @Fields ERROR_VALUE_MSG_TYPE_ERROR : 返回值的value 错误
	 */
	public static final String ERROR_VALUE_MSG_TYPE_ERROR = "error";

	/**
	 * @Fields ERROR_VALUE_OP_RESULT_SUCCESS : 返回值操作结果 成功
	 */
	public static final String ERROR_VALUE_OP_RESULT_SUCCESS = "0";

	/**
	 * @Fields ERROR_VALUE_OP_RESULT_FAIL : 返回值操作结果 失败
	 */
	public static final String ERROR_VALUE_OP_RESULT_FAIL = "1";

	/**
	 * @Fields ZTREE_ROOT_VALUE : ztree 根节点的值
	 */
	public static final String ZTREE_ROOT_NODE_VALUE = "-1";

	/**
	 * @Fields ERROR_VALUE_OP_RESULT_SUCCESS_NAME : 获取操作结果 成功字段
	 */
	public static final String ERROR_VALUE_OP_RESULT_SUCCESS_NAME = "Success";

	@InitBinder
	public void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
		binder.registerCustomEditor(Date.class, new DateEditor());
	}

	/**
	 * 将对象的不为空的属性进行复制（将copied中属性的值复制到duplicate中）
	 * 
	 * @param duplicate
	 * @param copied
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	public Object copyBeanNotEmptyFields(Object duplicate, Object copied)
			throws IllegalAccessException, InstantiationException {
		if (copied == null)
			return null;
		if (duplicate == null)
			duplicate = copied.getClass().newInstance();
		Field[] fields = copied.getClass().getDeclaredFields();
		for (Field field : fields) {
			field.setAccessible(true);
			Object fieldValueObject = field.get(copied);
			if (fieldValueObject != null) {// 判断是否为null，不为null就开始复制属性
				if (fieldValueObject instanceof String) {
					if (fieldValueObject.equals("")) {// 如果是String判断是否是空串，不为空串的才复制属性
						continue;
					}
				}
				field.set(duplicate, fieldValueObject);// 复制
			}
		}
		return duplicate;
	}

	// @Resource
	// ISysConfigService sysConfigService;

	/**
	 * 根据code获取返还至页面的文案信息
	 * 
	 * @param code
	 * @return
	 */
	public String returnMsg(String code) {
		ISysConfigService sysConfigService = (ISysConfigService) SpringContextUtil.getBean("sysConfigServiceImpl");
		return sysConfigService.findByCode(code).getValue();

	}

	/**
	 * 打印错误日志
	 * 
	 * @param e
	 * @throws IOException
	 */
	protected void logErr(Exception e) {
		ByteArrayOutputStream out = null;
		try {
			out = new ByteArrayOutputStream();
			PrintStream s = new PrintStream(out);
			e.printStackTrace(s);
			String string = new String(out.toByteArray());
			logger.error(string);
			logger.debug(string);
		} catch (Exception e1) {
			e1.printStackTrace();
		} finally {
			if (out != null)
				try {
					out.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
		}

	}
}
